package com.fcscs.cservice.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import com.fcscs.core.service.FcsManager;
import com.fcscs.core.system.ApplicationContextHolder;
import com.fcscs.core.util.CommonUtil;
import com.fcscs.cservice.common.CServiceReportConstants;
import com.fcscs.cservice.domain.Folio;
import com.fcscs.cservice.domain.Title;
import com.fcscs.cservice.domain.model.FolioViewForFile;
import com.fcscs.cservice.domain.model.RCView;
import com.fcscs.cservice.domain.model.RCViewForFile;
import com.fcscs.cservice.domain.model.RateViewForFile;
import com.fcscs.cservice.domain.model.ReservationView;
import com.fcscs.cservice.service.CServiceCommonManager;
import com.fcscs.cservice.service.ReportGeneratorManager;
import com.fcscs.cservice.service.ReservationManager;
import com.fcscs.share.common.ReportConstants;

@Service("reportGeneratorManager")
public class ReportGeneratorManagerImpl extends FcsManager implements ReportGeneratorManager {
	private long rcId;
	@Autowired
	private ReservationManager reservMgr;
	
	@Autowired
	CServiceCommonManager conMgr;

	@Override
	public byte[] getPDFReport(String reportName, Map<String, Object> parameters, Object ds) throws IOException,
			JRException {
		Resource res = ApplicationContextHolder.getApplicationContext().getResource(
				"classpath:jasper/" + reportName + ".jasper");
		String subreportDir = res.getFile().getParentFile().getAbsolutePath()+File.separator;
		parameters.put(CServiceReportConstants.SUBREPORT_DIR,subreportDir);
		InputStream in = res.getInputStream();
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		JasperPrint jasperPrint = fillReport(parameters, in, ds);
		JasperExportManager.exportReportToPdfStream(jasperPrint, baos);
		return baos.toByteArray();
	}
	
	
	@Override
	public byte[] getRCPDF(RCView rcView, Map<String, Object> parameters) throws IOException, JRException {
		ReservationView reservation = reservMgr.getReservationView(rcView.getReservationId());

		rcId = reservation.getRcs().get(0).getRcId();
		parameters.put(CServiceReportConstants.CONFIRMATIONNO, reservation.getConfirmationNo());
		String user = CommonUtil.getWsSessionUsername();
		parameters.put(CServiceReportConstants.GSA,user);
		parameters.put(CServiceReportConstants.NUMOFGUEST, reservation.getNumberOfGuest());
		parameters.put(CServiceReportConstants.ROOMSUITE, reservation.getRoomNumber());
		parameters.put(CServiceReportConstants.ROOMTYPE, reservation.getRoomType());
		parameters.put(CServiceReportConstants.SPGNO, reservation.getMemberships().size() > 0 ? reservation
				.getMemberships().get(0).getNumber() : null);

		RCViewForFile rcViewModel = reservMgr.getRCViewForFile(rcId);
		List<RCViewForFile> lv = new ArrayList<RCViewForFile>();
		lv.add(rcViewModel);
		parameters.put(CServiceReportConstants.LV, lv);
		List<RateViewForFile> roomRateList = rcViewModel.getRates();
		parameters.put(CServiceReportConstants.ROOMRATELIST, roomRateList);
		byte[] pdfReport = null;
		if (lv.size() != 0) {
			parameters.put(ReportConstants.DISPLAY_TOTAL, true);
			parameters.put(ReportConstants.DISPLAY_PAGE_FOOTER, true);
			pdfReport = getPDFReport("registrationCard", parameters, new JRBeanCollectionDataSource(lv, false));
		} else {
			parameters.put(ReportConstants.DISPLAY_TOTAL, true);
			parameters.put(ReportConstants.DISPLAY_PAGE_FOOTER, true);
			pdfReport = getPDFReport("blank", parameters, new JRBeanCollectionDataSource(lv, false));
		}
		return pdfReport;	
	}
	
	@Override
	public byte[] getFolioPDF(Folio folio, Map<String, Object> parameters) throws IOException, JRException {
		FolioViewForFile myFolio = reservMgr.getFolioViewForFile(folio.getId());
		Title title = null;
		if (null != myFolio.getTitleId()) {
			title = conMgr.getTitle(myFolio.getTitleId());
		}
		parameters.put(CServiceReportConstants.CURRENCY, myFolio.getCurrency());
		if (null != title) {
			parameters.put(CServiceReportConstants.TITLE, title.getTitle());
		}else{
			parameters.put(CServiceReportConstants.TITLE, "");
		}
		parameters.put(CServiceReportConstants.GENDER, myFolio.getGenderMale() ? CServiceReportConstants.MALE : CServiceReportConstants.FEMALE);
		List<FolioViewForFile> lv = new ArrayList<FolioViewForFile>();
		lv.add(myFolio);
		byte[] pdfReport = null;
		if (lv.size() != 0) {
			parameters.put(ReportConstants.DISPLAY_TOTAL, true);
			parameters.put(ReportConstants.DISPLAY_PAGE_FOOTER, true);
			pdfReport = getPDFReport("folioPdf", parameters, new JRBeanCollectionDataSource(lv, false));
		} else {
			parameters.put(ReportConstants.DISPLAY_TOTAL, true);
			parameters.put(ReportConstants.DISPLAY_PAGE_FOOTER, true);
			pdfReport = getPDFReport("blank", parameters, new JRBeanCollectionDataSource(lv, false));
		}
		return pdfReport;
	}
	
	private JasperPrint fillReport(Map<String, Object> parameters, InputStream in, Object ds) throws JRException {
		if (ds instanceof JRDataSource) {
			return JasperFillManager.fillReport(in, parameters, (JRDataSource) ds);
		} else {
			return JasperFillManager.fillReport(in, parameters, (Connection) ds);
		}
	}

}
